<?php
namespace app\shop\library\coupon;

use cubox\Cubox;
use app\shop\library\ApiController;
use app\shop\library\Snowflake;
use app\shop\library\coupon\CouponStock;
use app\shop\library\coupon\MemberCoupon;

class Coupon{
    public static function get($coupon_id){

        $key = ApiController::cacheName('coupon',$coupon_id);

        $shop = Cubox::app('shop');
        $cache = $shop->cache();

        if ($cache->exists($key)){
            return json_decode($cache->get($key)??'{}',true);
        }else{
            $coupon = $shop->model('Coupon');

            $data = $coupon->getId($coupon_id);

            if ($data){

                $data['_apply_goods_list'] = $data['apply_goods_list']??'';
                $data['_apply_cate_list'] = $data['apply_cate_list']??'';

                if ($data['apply_type'] !='all'){
                    if ($data['apply_goods_list']!='') $data['apply_goods_list'] = explode(',',$data['apply_goods_list']);
                   
                    if ($data['apply_cate_list']!=''){
                        $cate = $shop->model('Cate');

                        $cateList = [];

                        foreach (explode(',',$data['apply_cate_list']) as $cateId){
                            $cateList = array_unique(array_merge($cateList,$cate->getKeyCollect($cateId,true,true)));
                        }

                        $data['apply_cate_list'] = $cateList;
                    }
                }

                $cache->set($key,json_encode($data));
                return $data;
            }else{
                return null;
            }
        }
    }


    public static function saleList(){
        static $list;
        
        if ($list) return $list;
        $list = [];
        $shop = Cubox::app('shop');
        

        $key = ApiController::cacheName('coupon_sale_list');

        $cache = $shop->cache();

        if ($cache->exists($key)){
            $list = json_decode($cache->get($key)??'[]',true);
            
        }else{
           
            $coupon = $shop->model('Coupon');
            $data = $coupon->where('status','sale')->getData();
            
            foreach ($data as $key => $val){

                if ($val['apply_type'] !='all'){
                    if ($val['apply_goods_list']!='') $val['apply_goods_list'] = explode(',',$val['apply_goods_list']);
                   
                    if ($val['apply_cate_list']!=''){
                        $cate = $shop->model('Cate');

                        $cateList = [];

                        foreach (explode(',',$val['apply_cate_list']) as $cateId){
                            $cateList = array_unique(array_merge($cateList,$cate->getKeyCollect($cateId,true,true)));
                        }

                        $val['apply_cate_list'] = $cateList;
                    }
                }

                $list[$val['coupon_id']]= $val;

            }
        }

        return $list;
    }

     
    public static function clearCache($coupon_id=''){
        $shop = Cubox::app('shop');
        $cache = $shop->cache();

        if ($coupon_id!=''){
            $key = ApiController::cacheName('coupon',$coupon_id);
            $cache->delete($key);
        }
       

        $key = ApiController::cacheName('coupon_sale_list');
        $cache->delete($key);
    }


    public static function getGoodsCoupons($goods_id,$cate_id){
        $list = self::saleList();
        $goodsCoupon = [];

        foreach ($list as $val){
            $in =  false;
            if ($val['apply_type']=='all'){
                $in =  true;
            }else{

                if (in_array($goods_id,$val['apply_goods_list']??[])){
                    $in =  true;
                }

                if (in_array($cate_id,$val['apply_cate_list']??[])){
                    $in =  true;
                }
            }

            if ($in){
                $goodsCoupon[] = $val;
            }
        }

        return $goodsCoupon;           
    }

    /**
     * 领取优惠券
     * @param integer $coupon_id
     * @param integer $member_id
     * @param integer $num
     * @return void
     */
    public static function receive($coupon_id,$member_id){
        $shop = Cubox::app('shop');
        $couponData = self::get($coupon_id);

        if ($couponData === null){
            throw new \Exception('优惠券不存在');
        }

        if ($couponData['status'] != 'sale'){
            throw new \Exception('优惠券已下架');
        }


        $memberCoupun = $shop->model('MemberCoupon');
        $count = $memberCoupun->where('member_id',$member_id)->where('coupon_id',$coupon_id)->count();
        if ($count >= $couponData['member_receive_number']){
            throw new \Exception('优惠券已领取');
        }


        $snowflake =  new Snowflake($shop->cache(),'memberCoupun');
        $memberCoupunId = $snowflake->nextId();
        $data = [
            'member_id' => $member_id,
            'member_coupon_id' => $memberCoupunId,
        ];

        $data['coupon_id'] = $coupon_id;
        $data['coupon_starttime'] = $couponData['starttime'];
        $data['coupon_endtime'] = $couponData['endtime'];
        $data['coupon_type'] = $couponData['type'];
        $data['coupon_desc'] = $couponData['desc'];
        $data['coupon_price'] = $couponData['price'];
        $data['coupon_condition_price'] = $couponData['condition_price'];
        $data['coupon_apply_type'] = $couponData['apply_type'];
        $data['coupon_apply_goods_list'] = $couponData['_apply_goods_list'];
        $data['coupon_apply_cate_list'] = $couponData['_apply_cate_list'];

        //加锁
        if (!CouponStock::lock($coupon_id))  throw new \Exception('优惠券领取失败');
        if (CouponStock::reduce($coupon_id)){
            try{
                $memberCoupun->insert($data);
                MemberCoupon::updateExist($coupon_id,$count+1);
                CouponStock::unlock($coupon_id);
                return true;
            }catch(\Exception $e){
                CouponStock::recovery($coupon_id);
                CouponStock::unlock($coupon_id);
                throw new \Exception('优惠券领取失败');
            }
        }else{
            CouponStock::unlock($coupon_id);
            throw new \Exception('优惠券领取失败');
        }

        return false;
    }
}